using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using ZeroBlog.Core.Domains.Blog;
using ZeroSum.DependencyInjection.Attributes;
using ZeroSum.Domain.Repositories;
using ZeroSum.Exceptions;
using ZeroSum.Extend.EFCore.MySql.Extensions;

namespace ZeroBlog.Core.DomainServices.FlashArticles;

[Register(ServiceLifetime.Scoped)]
public class FlashArticleDomainService : IFlashArticleDomainService
{
    private readonly IRepository<FlashArticle> _repository;

    public FlashArticleDomainService(IRepository<FlashArticle> repository)
    {
        _repository = repository;
    }

    public async Task AddAsync(FlashArticle domain)
    {
        //if (await _repository.AnyAsync(x => x.Name == domain.Name))
        //    throw AlreadyExistedException.Of($"优先级中已存在名为{domain.Name}的项")!;
        await _repository.AddAsync(domain);
    }

    public async Task DeleteAsync(IList<long> ids)
    {
        //需要判断是不是所有id都在数据中存在
        await _repository.RemoveAsync(x => ids.Contains(x.Id));
    }

    public async Task UpdateAsync(FlashArticle domain)
    {
        if (!await _repository.AnyAsync(x => x.Id == domain.Id))
            throw AlreadyExistedException.Of($"优先级中不已存在编号为{domain.Id}的项")!;
        //if (await _repository.AnyAsync(x => x.Name == domain.Name && x.Id != domain.Id && !x.IsDeleted))
        //    throw AlreadyExistedException.Of($"优先级中已存在名为{domain.Name}的项")!;
        await _repository.UpdateAsync(domain);
    }

    public async Task<FlashArticle> GetAsync([NotNull] Expression<Func<FlashArticle, bool>> predicate)
    {
        return await _repository.GetAsync(predicate);
    }

    public async Task<(IList<FlashArticle>, int)> Query(string? keyword, int pageNumber, int pageSize)
    {
        var query = GetQueryBy(keyword);
        var count = await _repository.CountAsync(query);
        var result = await _repository.GetListAsync(query.Paged(pageNumber, pageSize));
        return (result, count);
    }

    private static QueryByEntity<FlashArticle> GetQueryBy(string? keyword)
    {
        var isEmpty = !string.IsNullOrEmpty(keyword?.Trim());
        IQueryable<FlashArticle> Func(IQueryable<FlashArticle> query)
        {
            return query.WhereIf(isEmpty,
                u => EF.Functions.Like(u.Title, $"%{keyword!.Trim()}%") ||
                     EF.Functions.Like(u.Title, $"%{keyword.Trim()}%")).OrderBy(x => x.Id);
        }

        var query = QueryByEntity<FlashArticle>.Of(Func);
        return query;
    }
}